﻿// *----------------------------------------------------------------
// Copyright (C) 2017 通通优品
// 版权所有。
// 
// 类名：DapperUnitOfWork.cs
// 功能描述：TongTongMall.Dapper
// 
// Create User：jym 2017/02/09
// 
// Edit User：UserName,EditTime
// Describe：Describe
// ----------------------------------------------------------------*/
using Castle.Core.Logging;
using System;
using System.Collections.Generic;
using System.Data;
using System.Runtime.Remoting.Messaging;
using System.Threading.Tasks;
using System.Transactions;
using TongTongMall.Dapper;
using TongTongMall.Dapper.DapperExtensions;
using TongTongMall.Dependecy;
using TongTongMall.Domain.Uow;

namespace TongTongMall.Dapper.Uow
{
    public class DapperUnitOfWork : UnitOfWorkBase, ITransientDependency
    {
        public ILogger Logger { get; set; }

        protected IIocResolver IocResolver { get; private set; }

        protected TransactionScope CurrentTransaction;

        protected DatabaseConnectionWrapper ActiveDatabaseConnectionWrappers;

        public DapperUnitOfWork(
              IIocResolver iocResolver,
              IConnectionStringResolver connectionStringResolver,
              IUnitOfWorkDefaultOptions defaultOptions)
              : base(connectionStringResolver, defaultOptions)
        {
            IocResolver = iocResolver;
            Logger = NullLogger.Instance;
        }

        protected override void BeginUow()
        {
            if (Options.IsTransactional == true)
            {
                var transactionOptions = new TransactionOptions
                {
                    IsolationLevel = Options.IsolationLevel.GetValueOrDefault(System.Transactions.IsolationLevel.ReadUncommitted),
                };

                if (Options.Timeout.HasValue)
                {
                    transactionOptions.Timeout = Options.Timeout.Value;
                }

                CurrentTransaction = new TransactionScope(
                    Options.Scope.GetValueOrDefault(TransactionScopeOption.Required),
                    transactionOptions,
                    Options.AsyncFlowOption.GetValueOrDefault(TransactionScopeAsyncFlowOption.Enabled)
                    );
            }
        }

        public virtual DatabaseConnectionWrapper GetOrSetDatabaseConnectionWrapper(Func<DatabaseConnectionWrapper> factory)
        {
            if (ActiveDatabaseConnectionWrappers == null)
            {
                ActiveDatabaseConnectionWrappers = factory();
            }
            if (ActiveDatabaseConnectionWrappers.IsTransactionConnection && ActiveDatabaseConnectionWrappers.Connection.State == ConnectionState.Closed)
            {
                ActiveDatabaseConnectionWrappers.Connection.Open();
            }
            return ActiveDatabaseConnectionWrappers;
        }

        protected override void CompleteUow()
        {
            SaveChanges();
            if (CurrentTransaction != null)
            {
                CurrentTransaction.Complete();
            }

            DisposeUow();
        }

        protected override async Task CompleteUowAsync()
        {
            await SaveChangesAsync();
            if (CurrentTransaction != null)
            {
                CurrentTransaction.Complete();
            }
            DisposeUow();
        }


        protected override void DisposeUow()
        {
            //Logger.Debug("UnitOfWorkId：" + this.Id);
            if (CurrentTransaction != null)
            {
                CurrentTransaction.Dispose();
                CurrentTransaction = null;
            }
            else
            {
                if (ActiveDatabaseConnectionWrappers != null)
                {
                    ActiveDatabaseConnectionWrappers.Dispose();
                }
            }
        }

        public override Task SaveChangesAsync()
        {
            return Task.FromResult<object>(null);
        } 

        public override void SaveChanges()
        {
        }
    }
}
